package com.vsoft.sms_cm;



import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Type;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.log4j.Logger;

import com.vsoft.framework.core.BaseException;
import com.vsoft.framework.core.BusiObj;
import com.vsoft.framework.core.Configuration;
import com.vsoft.framework.core.util.LogCollect;
import com.vsoft.test.XmlServTest;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
public class RedisProxy<T> implements ICacheObj<T> {
	private  Jedis vJedis = null;
	private  String vName = this.getClass().getName();
	private  Logger vLogger = Logger.getLogger(this.getClass());
	private  int vDataType = -1; //1 obj 2 string
	///////////////////////add at 20121014 增加redis pipleline支持
	private boolean bPipeline =false;
	private Pipeline p =null;
	@Override
	public void setPipeline(boolean flag)throws BaseException
	{
		bPipeline	=	flag;
		if(flag)
			p	=	vJedis.pipelined();
		else
		{
			if(p!=null)
				p.sync();
			p=null;
		}
	}
	///////////////////add at 20121014 增加redis pipleline支持   end
	public  RedisProxy () throws BaseException{

		init();
	}
	
	private void init() throws BaseException{
		BusiObj confBo = Configuration.getConfBO();
		BusiObj bo = confBo.getBusiObj("REDIS_SMS");
		vJedis = new Jedis(bo.getString("ServerAddress"),bo.getInt("Port","6379"),15000);
		
	}
	
	public void clear(){
		vJedis.flushDB();
	}
	private boolean dataExist(){
		if(vJedis.dbSize()>0)
			return true;
		else
			return false;
	}
	public void put(String key,ArrayList<BusiObj> val) throws BaseException{
		putObj(key,val);
	}
	public void put(String key,HashMap<String,String> val) throws BaseException{
		putObj(key,val);
	}
	private void putObj(String key,Object val) throws BaseException{
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos =null;
		try{
		oos =  new ObjectOutputStream(baos);
		oos.writeObject(val);	
		/////////////add at 20121014 增加redis pipleline支持
		if(bPipeline)
			p.set(key,new String(baos.toByteArray(),"iso-8859-1"));
		else
		////////////////// end
			vJedis.set(key,new String(baos.toByteArray(),"iso-8859-1"));
		}catch(Exception e){
			throw new BaseException(vName+"0001","加入数据到缓存出错:"+LogCollect.getStackLog(e));
		}finally{
			if(baos != null)
				try {
					baos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if(oos != null)
				try {
					oos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}

	
	private Object getObj(String key) throws BaseException
	{
		Object obj = null;
		String strVal = vJedis.get(key);
		ByteArrayInputStream bais = null;
		ObjectInputStream ios = null;
		if(strVal != null){
			try{
				 bais = new ByteArrayInputStream(strVal.getBytes("iso-8859-1"));//SafeEncoder.encode(strVal));
				 ios = new ObjectInputStream(bais);
				obj = ios.readObject();
			}catch(Exception e){
					throw new BaseException(vName+"0002","从缓存获取数据出错:"+LogCollect.getStackLog(e));
			}finally{
				if(bais != null)
					try {
						bais.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				if(ios != null)
					try {
						ios.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			}
		}
		return obj;
	}
	@Override
	public void setId(int index,boolean bClear) throws BaseException {
		vJedis.select(index);
		if(bClear)
			clear();
	}
	@Override
	public void put(String key, T val) throws BaseException {
		// TODO Auto-generated method stub
		if(vDataType == -1){
			if(val instanceof String)
				vDataType = 2;
			else if (val instanceof ArrayList)
				vDataType = 1;
			else if (val instanceof HashMap)
				vDataType = 3;
		}
		if(vDataType == 1 ){
			putObj(key,val);			
		}else if (vDataType == 3 ){
			
			vJedis.hmset(key, (HashMap<String,String>)val);
		}
		else{
			vJedis.set(key, (String)val);
		}
	}
	@Override
	public T get(String key) throws BaseException {
		Object o = null;
		
		if(vDataType == 1){
			o = getObj(key);
		}else if(vDataType == 3){
			o = vJedis.hgetAll(key); 
		}
		else if(vDataType == -1){
			return null;
		}else
			
			o = vJedis.get(key);
		
		if(o != null)
			return (T) o;
		else
			return null;
	}
	@Override
	public void remove(String key) {
		vJedis.del(key);
		
	}
	@Override
	public String hmGet(String key, String field) {
		return vJedis.hget(key, field);
	
	}

	@Override
	public void setType(int iType) {
		// TODO Auto-generated method stub
		vDataType = iType;
	}

}
